package it.ap.sa.core.audit.config;

import java.util.ArrayList;
import java.util.List;

import org.audit4j.core.AuditManager;
import org.audit4j.core.Configuration;
import org.audit4j.core.handler.ConsoleAuditHandler;
import org.audit4j.core.handler.Handler;
import org.audit4j.core.layout.SimpleLayout;
import org.audit4j.handler.db.CustomDatabaseAuditHandler;
import org.audit4j.integration.spring.AuditAspect;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.EnableAspectJAutoProxy;
import org.springframework.stereotype.Service;

import it.ap.sa.core.utils.CoreProperties;


/**
 * Funzione di utility per la gestione di Audit4j (start/stop/configure)
 *  
 * @author marianna
 */
@Service
@EnableAspectJAutoProxy
public class AuditConfig {
	
	@Autowired
	private CoreProperties property;

	/**
	 * Per abilitare l'uso dell'annotation @Audit
	 * 
	 * <bean id="auditAspect" class="org.audit4j.integration.spring.AuditAspect" />
	 * 
	 * @EnableAspectJAutoProxy
	 * 
	 * o usare 
	 * 
	 * <aop:aspectj-autoproxy>
	 * 	  <aop:include name="auditAspect" />
	 * </aop:aspectj-autoproxy>
	 */
	@Bean
    public AuditAspect auditAspect() {
        AuditAspect auditAspect = new AuditAspect();
        return auditAspect;
    }

	/**
	 * Dopo questa configurazione Audit4j registrerà tutti gli eventi di controllo nel database definito. 
	 * Il file di database verrà creata automaticamente nella classe-percorso. 
	 * Se si desidera configurare qualsiasi altro database, consultare la sezione di configurazione del database sottostante.
	 * 
	 * @return {@link CustomDatabaseAuditHandler}
	 */
    public CustomDatabaseAuditHandler databaseHandler() {
    	/**
    	 * Configurazione del database in cui saranno registrati tutti gli eventi di controllo.
    	 */
    	CustomDatabaseAuditHandler dbHandler = new CustomDatabaseAuditHandler();
	        /** The embeded. */
	        dbHandler.setEmbedded("false");
	        // Sets the db_url 
	        dbHandler.setDb_url(property.jdbcUrl);
	        // Sets the db_user 
	        dbHandler.setDb_user(property.jdbcUsername);
	        // Sets the db_password 
	        dbHandler.setDb_password(property.jdbcPassword);
	        // Sets the db_driver.
	        dbHandler.setDb_driver(property.jdbcDriver);
//	        // Sets the db_datasource class.
	        dbHandler.setDb_datasourceClass(property.jdbcDatasourceClass);
	        // Sets the db_connection_type.
//	        dbHandler.setDb_connection_type(property.audit4jDbConnectionType);
	        // Sets the table_prefix.
	        dbHandler.setTable_prefix(property.audit4jDbPrefix);
	        // Sets the table_suffix.
	        dbHandler.setTable_suffix(property.audit4jDbSuffix);
        
        return dbHandler;
    }

    public Configuration getConfiguration() {
    	/**
    	 * Audit4j salverà gli eventi di controllo sia sul db che scritti in console.
    	 */
    	List<Handler> handlers = new ArrayList<Handler>();
	        handlers.add(new ConsoleAuditHandler());
	        handlers.add(databaseHandler());
	        
        Configuration configuration = new Configuration();
	        configuration.setLayout(new SimpleLayout());
	        configuration.setHandlers(handlers);
	        configuration.setMetaData(new AuditMetaData());
	        
        return configuration;
    }
    
    /**
     * This method allows to external plugins can inject the configurations.
     * Since the security reasons, this allows to create one time configuration
     * setting to Audit4j.
     * 
     * @param configuration
     */
    public void startWithConfiguration(){
    	AuditManager.startWithConfiguration(getConfiguration());
    	AuditManager.enable();
    }
    
    /**
     * 
     */
    public void shutdown(){
    	AuditManager.disable();
    	AuditManager.shutdown();
    }
}